//! # RustCloud 依赖注入模块
//!
//! 本模块提供了一个轻量级的依赖注入容器，用于管理RustCloud框架中各组件之间的依赖关系。
//! 通过依赖注入，我们可以消除模块间的直接耦合，提高代码的可测试性和可维护性。
//!
//! ## 设计原则
//!
//! * **接口隔离** - 组件只依赖于抽象接口，不依赖具体实现
//! * **单一职责** - 每个组件只负责自己的核心功能
//! * **控制反转** - 依赖关系由容器管理，而不是组件自己创建
//! * **生命周期管理** - 容器管理组件的创建、配置和销毁
//!
//! ## 使用示例
//!
//! ```rust
//! use rustcloud_core::di::*;
//! use rustcloud_core::*;
//! use std::sync::Arc;
//!
//! // 创建容器
//! let mut container = DIContainer::new();
//!
//! // 注册组件
//! container.register::<dyn ServiceRegistry>(|_| {
//!     Arc::new(InMemoryRegistry::new())
//! });
//!
//! container.register::<dyn LoadBalancer>(|_| {
//!     Arc::new(RoundRobinLoadBalancer::new())
//! });
//!
//! // 解析依赖
//! let registry = container.resolve::<dyn ServiceRegistry>().unwrap();
//! let load_balancer = container.resolve::<dyn LoadBalancer>().unwrap();
//! ```

use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use std::fmt;
use crate::{ServiceResult, ServiceError};

// =============================================================================
// 依赖注入容器核心
// =============================================================================

/// 依赖注入容器
/// 
/// 管理组件的注册、解析和生命周期。支持单例和瞬态生命周期。
pub struct DIContainer {
    /// 组件工厂映射
    factories: HashMap<TypeId, Box<dyn ComponentFactory>>,
    /// 单例实例缓存
    singletons: Arc<RwLock<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>>,
    /// 组件元数据
    metadata: HashMap<TypeId, ComponentMetadata>,
}

impl DIContainer {
    /// 创建新的依赖注入容器
    pub fn new() -> Self {
        Self {
            factories: HashMap::new(),
            singletons: Arc::new(RwLock::new(HashMap::new())),
            metadata: HashMap::new(),
        }
    }

    /// 注册单例组件
    /// 
    /// 单例组件在容器中只会创建一次，后续解析都返回同一个实例。
    pub fn register_singleton<T, F>(&mut self, name: Option<&str>, factory: F)
    where
        T: Any + Send + Sync + 'static,
        F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
    {
        let type_id = TypeId::of::<T>();
        self.factories.insert(type_id, Box::new(SingletonFactory::new(factory)));
        self.metadata.insert(type_id, ComponentMetadata {
            name: name.map(|s| s.to_string()).unwrap_or_else(|| std::any::type_name::<T>().to_string()),
            lifetime: ComponentLifetime::Singleton,
            dependencies: Vec::new(),
        });
    }

    /// 注册瞬态组件
    /// 
    /// 瞬态组件每次解析都会创建新的实例。
    pub fn register_transient<T, F>(&mut self, name: Option<&str>, factory: F)
    where
        T: Any + Send + Sync + 'static,
        F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
    {
        let type_id = TypeId::of::<T>();
        self.factories.insert(type_id, Box::new(TransientFactory::new(factory)));
        self.metadata.insert(type_id, ComponentMetadata {
            name: name.map(|s| s.to_string()).unwrap_or_else(|| std::any::type_name::<T>().to_string()),
            lifetime: ComponentLifetime::Transient,
            dependencies: Vec::new(),
        });
    }

    /// 注册已存在的实例
    /// 
    /// 直接注册一个已创建的实例作为单例。
    pub fn register_instance<T>(&mut self, name: Option<&str>, instance: Arc<T>)
    where
        T: Any + Send + Sync + 'static,
    {
        let type_id = TypeId::of::<T>();
        self.singletons.write().unwrap().insert(type_id, instance);
        self.metadata.insert(type_id, ComponentMetadata {
            name: name.map(|s| s.to_string()).unwrap_or_else(|| std::any::type_name::<T>().to_string()),
            lifetime: ComponentLifetime::Singleton,
            dependencies: Vec::new(),
        });
    }

    /// 解析组件
    /// 
    /// 根据类型解析并返回组件实例。
    pub fn resolve<T>(&self) -> ServiceResult<Arc<T>>
    where
        T: Any + Send + Sync + 'static,
    {
        let type_id = TypeId::of::<T>();
        
        // 首先检查单例缓存
        if let Some(instance) = self.singletons.read().unwrap().get(&type_id) {
            return instance
                .clone()
                .downcast::<T>()
                .map_err(|_| ServiceError::DIError(
                    format!("Failed to downcast component: {}", std::any::type_name::<T>())
                ));
        }

        // 使用工厂创建实例
        if let Some(factory) = self.factories.get(&type_id) {
            let instance = factory.create(self)?;
            let typed_instance = instance
                .downcast::<T>()
                .map_err(|_| ServiceError::DIError(
                    format!("Failed to downcast factory result: {}", std::any::type_name::<T>())
                ))?;

            // 如果是单例，缓存实例
            if let Some(metadata) = self.metadata.get(&type_id) {
                if metadata.lifetime == ComponentLifetime::Singleton {
                    self.singletons.write().unwrap().insert(type_id, typed_instance.clone());
                }
            }

            Ok(typed_instance)
        } else {
            Err(ServiceError::DIError(
                format!("Component not registered: {}", std::any::type_name::<T>())
            ))
        }
    }

    /// 检查组件是否已注册
    pub fn is_registered<T>(&self) -> bool
    where
        T: Any + 'static,
    {
        self.factories.contains_key(&TypeId::of::<T>())
    }

    /// 获取注册的组件数量
    pub fn component_count(&self) -> usize {
        self.factories.len()
    }

    /// 获取组件元数据
    pub fn get_metadata<T>(&self) -> Option<&ComponentMetadata>
    where
        T: Any + 'static,
    {
        self.metadata.get(&TypeId::of::<T>())
    }

    /// 列出所有注册的组件
    pub fn list_components(&self) -> Vec<&ComponentMetadata> {
        self.metadata.values().collect()
    }

    /// 清空容器
    pub fn clear(&mut self) {
        self.factories.clear();
        self.singletons.write().unwrap().clear();
        self.metadata.clear();
    }

    /// 验证容器配置
    /// 
    /// 检查是否存在循环依赖等问题。
    pub fn validate(&self) -> ServiceResult<()> {
        // TODO: 实现循环依赖检测
        Ok(())
    }
}

impl Default for DIContainer {
    fn default() -> Self {
        Self::new()
    }
}

impl fmt::Debug for DIContainer {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("DIContainer")
            .field("component_count", &self.component_count())
            .field("components", &self.list_components())
            .finish()
    }
}

// =============================================================================
// 组件工厂trait
// =============================================================================

/// 组件工厂trait
trait ComponentFactory: Send + Sync {
    fn create(&self, container: &DIContainer) -> ServiceResult<Arc<dyn Any + Send + Sync>>;
}

/// 单例工厂
struct SingletonFactory<T, F>
where
    T: Any + Send + Sync + 'static,
    F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
{
    factory_fn: F,
    _phantom: std::marker::PhantomData<T>,
}

impl<T, F> SingletonFactory<T, F>
where
    T: Any + Send + Sync + 'static,
    F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
{
    fn new(factory_fn: F) -> Self {
        Self {
            factory_fn,
            _phantom: std::marker::PhantomData,
        }
    }
}

impl<T, F> ComponentFactory for SingletonFactory<T, F>
where
    T: Any + Send + Sync + 'static,
    F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
{
    fn create(&self, container: &DIContainer) -> ServiceResult<Arc<dyn Any + Send + Sync>> {
        let instance = (self.factory_fn)(container);
        Ok(instance)
    }
}

/// 瞬态工厂
struct TransientFactory<T, F>
where
    T: Any + Send + Sync + 'static,
    F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
{
    factory_fn: F,
    _phantom: std::marker::PhantomData<T>,
}

impl<T, F> TransientFactory<T, F>
where
    T: Any + Send + Sync + 'static,
    F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
{
    fn new(factory_fn: F) -> Self {
        Self {
            factory_fn,
            _phantom: std::marker::PhantomData,
        }
    }
}

impl<T, F> ComponentFactory for TransientFactory<T, F>
where
    T: Any + Send + Sync + 'static,
    F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
{
    fn create(&self, container: &DIContainer) -> ServiceResult<Arc<dyn Any + Send + Sync>> {
        let instance = (self.factory_fn)(container);
        Ok(instance)
    }
}

// =============================================================================
// 组件元数据
// =============================================================================

/// 组件元数据
#[derive(Debug, Clone)]
pub struct ComponentMetadata {
    /// 组件名称
    pub name: String,
    /// 组件生命周期
    pub lifetime: ComponentLifetime,
    /// 依赖列表
    pub dependencies: Vec<String>,
}

/// 组件生命周期
#[derive(Debug, Clone, PartialEq)]
pub enum ComponentLifetime {
    /// 单例 - 容器中只创建一次
    Singleton,
    /// 瞬态 - 每次解析都创建新实例
    Transient,
}

// =============================================================================
// 便利宏
// =============================================================================

/// 简化组件注册的宏
/// 
/// # 示例
/// 
/// ```rust
/// register_component!(container, ServiceRegistry => InMemoryRegistry::new());
/// register_component!(container, LoadBalancer => RoundRobinLoadBalancer::new(), singleton);
/// ```
#[macro_export]
macro_rules! register_component {
    ($container:expr, $trait:ty => $impl:expr) => {
        $container.register_transient::<$trait>(None, |_| Arc::new($impl));
    };
    ($container:expr, $trait:ty => $impl:expr, singleton) => {
        $container.register_singleton::<$trait>(None, |_| Arc::new($impl));
    };
    ($container:expr, $trait:ty => $impl:expr, transient) => {
        $container.register_transient::<$trait>(None, |_| Arc::new($impl));
    };
    ($container:expr, $name:expr, $trait:ty => $impl:expr) => {
        $container.register_transient::<$trait>(Some($name), |_| Arc::new($impl));
    };
    ($container:expr, $name:expr, $trait:ty => $impl:expr, singleton) => {
        $container.register_singleton::<$trait>(Some($name), |_| Arc::new($impl));
    };
    ($container:expr, $name:expr, $trait:ty => $impl:expr, transient) => {
        $container.register_transient::<$trait>(Some($name), |_| Arc::new($impl));
    };
}

/// 解析组件的宏
/// 
/// # 示例
/// 
/// ```rust
/// let registry = resolve!(container, ServiceRegistry);
/// ```
#[macro_export]
macro_rules! resolve {
    ($container:expr, $trait:ty) => {
        $container.resolve::<$trait>()
    };
}

// =============================================================================
// 预定义组件工厂
// =============================================================================

/// RustCloud组件工厂
/// 
/// 提供常用组件的便利注册方法。
pub struct RustCloudComponentFactory;

impl RustCloudComponentFactory {
    /// 注册所有核心组件
    /// 
    /// 注意：这个方法应该由具体的应用程序实现，而不是在核心模块中直接依赖具体实现
    pub fn register_core_components(container: &mut DIContainer) -> ServiceResult<()> {
        // 这里只提供示例，实际使用时应该在应用程序中注册具体的实现
        
        // 示例：注册内存注册中心
        // container.register_singleton::<dyn crate::ServiceRegistry>(
        //     Some("memory-registry"),
        //     |_| Arc::new(SomeConcreteRegistry::new())
        // );
        
        // 示例：注册负载均衡器
        // container.register_singleton::<dyn crate::LoadBalancer>(
        //     Some("round-robin-lb"),
        //     |_| Arc::new(SomeConcreteLoadBalancer::new())
        // );
        
        tracing::warn!("register_core_components called but no implementations registered. This should be implemented in the application layer.");
        Ok(())
    }

    /// 注册测试组件
    /// 
    /// 注意：这个方法应该由测试代码使用 rustcloud-test-utils 中的 Mock 组件
    #[cfg(test)]
    pub fn register_test_components(container: &mut DIContainer) -> ServiceResult<()> {
        // 这里只提供示例，实际使用时应该使用 rustcloud-test-utils
        
        // 示例：使用 rustcloud-test-utils 中的 Mock 组件
        // use rustcloud_test_utils::*;
        // container.register_singleton::<dyn crate::ServiceRegistry>(
        //     Some("mock-registry"),
        //     |_| Arc::new(MockRegistry::new())
        // );
        
        tracing::warn!("register_test_components called but no test implementations registered. Use rustcloud-test-utils for Mock components.");
        Ok(())
    }

    /// 注册配置驱动的组件
    /// 
    /// 注意：这个方法应该由具体的应用程序实现
    pub fn register_from_config(
        container: &mut DIContainer,
        config: &crate::config_unified::UnifiedConfig,
    ) -> ServiceResult<()> {
        // 这里只提供示例，实际使用时应该在应用程序中根据配置注册具体实现
        
        // 示例：根据配置注册注册中心
        match config.registry.registry_type.as_str() {
            "nacos" => {
                // container.register_singleton::<dyn crate::ServiceRegistry>(
                //     Some("nacos-registry"),
                //     |_| Arc::new(NacosRegistry::new(endpoints, namespace, group).unwrap())
                // );
                tracing::info!("Would register Nacos registry");
            },
            "consul" => {
                // container.register_singleton::<dyn crate::ServiceRegistry>(
                //     Some("consul-registry"), 
                //     |_| Arc::new(ConsulRegistry::new(endpoints).unwrap())
                // );
                tracing::info!("Would register Consul registry");
            },
            "memory" | _ => {
                // container.register_singleton::<dyn crate::ServiceRegistry>(
                //     Some("memory-registry"),
                //     |_| Arc::new(InMemoryRegistry::new())
                // );
                tracing::info!("Would register Memory registry");
            }
        }

        // 示例：根据配置注册负载均衡器
        match config.load_balancer.strategy {
            crate::config_unified::LoadBalancerStrategy::RoundRobin => {
                tracing::info!("Would register RoundRobin load balancer");
            },
            crate::config_unified::LoadBalancerStrategy::Random => {
                tracing::info!("Would register Random load balancer");
            },
            crate::config_unified::LoadBalancerStrategy::WeightedRoundRobin => {
                tracing::info!("Would register WeightedRoundRobin load balancer");
            },
            _ => {
                tracing::info!("Would register default load balancer");
            }
        }
        
        tracing::warn!("register_from_config called but no implementations registered. This should be implemented in the application layer.");
        Ok(())
    }
}

// =============================================================================
// 服务定位器模式（可选）
// =============================================================================

/// 全局服务定位器
/// 
/// 提供全局访问依赖注入容器的方式。注意：应该谨慎使用，优先使用构造函数注入。
#[derive(Clone)]
pub struct ServiceLocator {
    container: Arc<RwLock<DIContainer>>,
}

impl ServiceLocator {
    /// 创建新的服务定位器
    pub fn new(container: DIContainer) -> Self {
        Self {
            container: Arc::new(RwLock::new(container)),
        }
    }

    /// 解析服务
    pub fn resolve<T>(&self) -> ServiceResult<Arc<T>>
    where
        T: Any + Send + Sync + 'static,
    {
        self.container.read().unwrap().resolve::<T>()
    }

    /// 注册服务
    pub fn register_singleton<T, F>(&self, name: Option<&str>, factory: F)
    where
        T: Any + Send + Sync + 'static,
        F: Fn(&DIContainer) -> Arc<T> + Send + Sync + 'static,
    {
        self.container.write().unwrap().register_singleton(name, factory);
    }

    /// 获取容器的只读引用
    pub fn container(&self) -> std::sync::RwLockReadGuard<DIContainer> {
        self.container.read().unwrap()
    }
}

// 全局服务定位器实例（可选）
lazy_static::lazy_static! {
    static ref GLOBAL_SERVICE_LOCATOR: std::sync::Mutex<Option<ServiceLocator>> = 
        std::sync::Mutex::new(None);
}

/// 设置全局服务定位器
pub fn set_global_service_locator(locator: ServiceLocator) {
    *GLOBAL_SERVICE_LOCATOR.lock().unwrap() = Some(locator);
}

/// 获取全局服务定位器
pub fn get_global_service_locator() -> Option<ServiceLocator> {
    GLOBAL_SERVICE_LOCATOR.lock().unwrap().as_ref().cloned()
}

#[cfg(test)]
mod tests {
    use super::*;
    use rustcloud_test_utils::*;

    #[test]
    fn test_di_container_basic() {
        let mut container = DIContainer::new();
        
        // 注册组件
        container.register_singleton::<dyn rustcloud_core::ServiceRegistry>(
            Some("test-registry"),
            |_| Arc::new(MockRegistry::new())
        );

        // 解析组件
        let registry = container.resolve::<dyn rustcloud_core::ServiceRegistry>().unwrap();
        assert_eq!(registry.name(), "mock-registry");
        
        // 验证单例行为
        let registry2 = container.resolve::<dyn rustcloud_core::ServiceRegistry>().unwrap();
        assert!(Arc::ptr_eq(&registry, &registry2));
    }

    #[test]
    fn test_component_metadata() {
        let mut container = DIContainer::new();
        
        container.register_singleton::<dyn rustcloud_core::ServiceRegistry>(
            Some("test-registry"),
            |_| Arc::new(MockRegistry::new())
        );

        let metadata = container.get_metadata::<dyn rustcloud_core::ServiceRegistry>().unwrap();
        assert_eq!(metadata.name, "test-registry");
        assert_eq!(metadata.lifetime, ComponentLifetime::Singleton);
    }

    #[test]
    fn test_register_core_components() {
        let mut container = DIContainer::new();
        RustCloudComponentFactory::register_core_components(&mut container).unwrap();
        
        assert!(container.is_registered::<dyn rustcloud_core::ServiceRegistry>());
        assert!(container.is_registered::<dyn rustcloud_core::LoadBalancer>());
        assert!(container.is_registered::<dyn rustcloud_core::Transport>());
    }

    #[test]
    fn test_macro_usage() {
        let mut container = DIContainer::new();
        
        // 使用宏注册组件
        register_component!(container, dyn rustcloud_core::ServiceRegistry => MockRegistry::new(), singleton);
        register_component!(container, dyn rustcloud_core::LoadBalancer => MockLoadBalancer::new());
        
        // 使用宏解析组件
        let registry = resolve!(container, dyn rustcloud_core::ServiceRegistry).unwrap();
        let lb = resolve!(container, dyn rustcloud_core::LoadBalancer).unwrap();
        
        assert_eq!(registry.name(), "mock-registry");
        assert_eq!(lb.name(), "mock-load-balancer");
    }
}